package com.xbts.screen.monitor.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbts.common.core.constant.CacheConstants;
import com.xbts.common.core.utils.StringUtils;
import com.xbts.common.core.web.page.TableDataInfo;
import com.xbts.common.redis.service.RedisService;
import com.xbts.screen.monitor.domain.MonitorDetailsVO;
import com.xbts.screen.monitor.domain.WeMonitorConnectConfig;
import com.xbts.screen.monitor.domain.WeMonitorQueryParameter;
import com.xbts.screen.monitor.domain.constant.MonitorConstant;
import com.xbts.screen.monitor.domain.http.HttpConfigInfo;
import com.xbts.screen.monitor.domain.request.DeviceListRequest;
import com.xbts.screen.monitor.domain.request.PlayBackFormatEnum;
import com.xbts.screen.monitor.domain.request.RealTimeRequest;
import com.xbts.screen.monitor.domain.response.DeviceListResponse;
import com.xbts.screen.monitor.domain.response.RealTimeResponse;
import com.xbts.screen.monitor.domain.util.HttpURLConnectionUtil;
import com.xbts.screen.monitor.domain.util.HttpsURLConnectionUtil;
import com.xbts.screen.monitor.domain.util.UrlUtil;
import com.xbts.screen.monitor.service.IWeMonitorConnectConfigService;
import com.xbts.screen.monitor.service.IWeMonitorQueryParameterService;
import com.xbts.screen.monitor.domain.request.GetTokenRequest;
import com.xbts.screen.monitor.domain.response.GetTokenResponse;
import com.xbts.screen.monitor.domain.token.OauthConfigBaseInfo;
import com.xbts.screen.monitor.domain.token.OauthConfigUserPwdInfo;
import com.xbts.screen.monitor.service.IMonitorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 药水化验品质
 */
@Slf4j
@Service
public class MonitorServerImpl implements IMonitorService {

    @Autowired
    private RedisService redisService;
    @Autowired
    private IWeMonitorConnectConfigService monitorConnectConfigService;
    @Autowired
    private IWeMonitorQueryParameterService monitorQueryParameterService;

    @Override
    public TableDataInfo list(Long pageNum, Long pageSize) {
        WeMonitorConnectConfig connectConfig = monitorConnectConfigService.list().get(0);
        WeMonitorQueryParameter queryParameter = monitorQueryParameterService.list().get(0);
        OauthConfigUserPwdInfo oauthConfigUserPwdInfo = getOauthConfigUserPwdInfo(connectConfig);
        //发送请求
        DeviceListRequest deviceListRequest = new DeviceListRequest(oauthConfigUserPwdInfo);
        if (pageNum != null) {
            deviceListRequest.setPageNum(pageNum);
        }
        if (pageSize != null) {
            deviceListRequest.setPageSize(pageSize);
        }
        BeanUtils.copyProperties(queryParameter, deviceListRequest);
        if(StringUtils.isNotBlank(queryParameter.getUnitTypeList())){
            String[] split = queryParameter.getUnitTypeList().split(",");
            List<Integer> unitTypeList = new ArrayList<>();
            for (String s : split) {
                unitTypeList.add(Integer.parseInt(s));
            }
            deviceListRequest.setUnitTypeList(unitTypeList);
        }
        DeviceListResponse deviceListResponse = deviceListRequest.doAction();
        DeviceListResponse.PageVO pageVO = deviceListResponse.getData();
        if (pageVO == null) {
            return null;
        }
        // 总条数
        Integer totalRows = pageVO.getTotalRows();
        List<DeviceListResponse.ChannelInfoVO> voList = pageVO.getPageData();
        List<MonitorDetailsVO> list = new ArrayList<>();
        if(totalRows == 0){
            return new TableDataInfo(list, totalRows);
        }



        for (DeviceListResponse.ChannelInfoVO channelInfoVO : voList) {
            MonitorDetailsVO vo = new MonitorDetailsVO();
            vo.setDeviceCode(channelInfoVO.getDeviceCode());
            vo.setDeviceName(channelInfoVO.getChannelName());
            vo.setChannelCode(channelInfoVO.getChannelCode());
            vo.setIsOnline(channelInfoVO.getIsOnline());
            // 获取播放地址
            RealTimeRequest request = new RealTimeRequest(oauthConfigUserPwdInfo);
            request.setChannelId(channelInfoVO.getChannelCode());
            request.setStreamType("1");
            request.setDataType("1");
            request.setType(PlayBackFormatEnum.RTSP.getCode());
            RealTimeResponse realTimeResponse = null;

//            if(PlayBackFormatEnum.RTSP.getCode().equals(request.getType())){
                realTimeResponse = getRTSPRealTimeUrl(request);
//            }else{
//                realTimeResponse = getHLSFLVRTMPRealTimeUrl(request);
//            }
            if(realTimeResponse != null) {
                RealTimeResponse.RealTimeResponseData data = realTimeResponse.getData();
                if (data != null) {
                    vo.setUrl(data.getUrl());
                    vo.setToken(data.getToken());
                }
            }
            list.add(vo);
        }
        return new TableDataInfo(list, totalRows);

    }

    private String getToken(){
        String token  = redisService.getCacheObject(CacheConstants.ICC_TOKEN);
        if(StringUtils.isNotBlank(token)){
            return token;
        }
        WeMonitorConnectConfig config = monitorConnectConfigService.list().get(0);
        OauthConfigUserPwdInfo oauthConfigUserPwdInfo = getOauthConfigUserPwdInfo(config);
        GetTokenRequest request = new GetTokenRequest(oauthConfigUserPwdInfo);
        GetTokenResponse getTokenResponse = request.doAction();
        String access_token = getTokenResponse.getData().getAccess_token();
        redisService.setCacheObject(CacheConstants.ICC_TOKEN, access_token, CacheConstants.ICC_TOKEN_TIME_OUT, TimeUnit.MINUTES);
        return access_token;
    }
    private OauthConfigUserPwdInfo getOauthConfigUserPwdInfo(WeMonitorConnectConfig config){
        OauthConfigUserPwdInfo oauthConfigUserPwdInfo = new OauthConfigUserPwdInfo(config.getHost(),
                config.getClientId(),
                config.getClientSecret(),
                config.getUsername(),
                config.getPassword(),
                config.isEnableHttpTest(),
                config.getHttps(),
                config.getHttp());;
        return oauthConfigUserPwdInfo;
    }

    /**
     * 获取RTSP实时流
     * **/
    private RealTimeResponse getRTSPRealTimeUrl(RealTimeRequest request) {
        RealTimeResponse realTimeResponse = request.doAction();
        if(!"1000".equals(realTimeResponse.getCode())){
            log.error("Acquire RTSP stream'URL fail,code:{},errorMsg:{}",realTimeResponse.getCode(),realTimeResponse.getErrMsg());
            return null;
        }
        //对结果进行处理
        RealTimeResponse.RealTimeResponseData realTimeResponseData = realTimeResponse.getData();
        if(realTimeResponseData == null){
            log.info("Acquired RTSP stream address is Empty.");
            return null;
        }
        String rtspUrls = realTimeResponseData.getUrl();
        String token = realTimeResponseData.getToken();
        String[] rtspUrlArr = rtspUrls.split("\\|");
        List<String> list = new ArrayList<String>();
        if(rtspUrlArr == null || rtspUrlArr.length == 0){
            log.info("Acquired RTSP stream address is Empty.");
            return null;
        }
        for(String item : rtspUrlArr){
            list.add(item + "?token=" + token);
        }
        realTimeResponse.setUrlList(list);
        return realTimeResponse;
    }

    /**
     * 获取HLS/FLV/RTMP实时流
     * **/
    private RealTimeResponse getHLSFLVRTMPRealTimeUrl(RealTimeRequest request) {
        RealTimeResponse realTimeResponse = request.doAction();
        if(!"1000".equals(realTimeResponse.getCode())){
            log.error("Acquire HLS/FLV/RTMP stream'URL fail,code:{},errorMsg:{}.",realTimeResponse.getCode(),realTimeResponse.getErrMsg());
            return null;
        }
        //对结果进行处理
        RealTimeResponse.RealTimeResponseData realTimeResponseData = realTimeResponse.getData();
        if(realTimeResponseData == null){
            log.info("Acquired HLS/FLV/RTMP stream's URL is empty.");
            return null;
        }
        String rtspUrls = realTimeResponseData.getUrl();
        String token = realTimeResponseData.getToken();
        String[] rtspUrlArr = rtspUrls.split("\\|");
        List<String> list = new ArrayList<String>();
        if(rtspUrlArr == null || rtspUrlArr.length == 0){
            log.info("Acquired HLS/FLV/RTMP stream's URL is empty.");
            return null;
        }
        for(String item : rtspUrlArr){
            if(!org.springframework.util.StringUtils.isEmpty(token)){
                list.add(item + "?token=" + token);
            } else{
                list.add(item);
            }
        }
        realTimeResponse.setUrlList(list);
        return realTimeResponse;
    }


}